#pragma once

#include <boost/program_options.hpp>

/**
  *  Program options macros
  */

namespace po = boost::program_options;
#define PO_VARIABLE(var, vm, param, type) type var(vm[param].as<type>())
#define PO_VARIABLE_VALUE(var, vm, param, type) { var = (vm[param].as<type>()); }
#define PO_VARIABLE_DEFAULT(var, vm, param, type, default_value) type var(vm.count(param) ? vm[param].as<type>() : default_value)
#define PO_REQUIRE(vm, param) if ( !(vm).count(param) ) { std::cerr << "require --" << param << std::endl; exit(1); }

/**
  *  Other Boost macros
  */
#define BOOST_split(line, tokens, delim) boost::split(tokens, line, boost::algorithm::is_any_of(delim), boost::algorithm::token_compress_on); \
    tokens.erase(std::remove_if(tokens.begin(), tokens.end(), boost::bind(&std::string::empty, _1)), tokens.end());


/**
  *  Standard Template Library macros
  */

#define SZ(container) ((int)(container.size()))
#define ALL(container) (container).begin(), (container).end()
#define TR(container, iterator) for (auto iterator = (container).begin(); iterator != (container).end(); iterator++)

#define MSG(m) { std::cerr << m << std::endl; }
#define MSG_VERBOSE(vm, m) { if (vm.count("verbose")) { std::cerr << m << std::endl; } }
#define FATAL(m) { MSG(m); exit(1); }
/**
  *  Armadillo macros
  */

